﻿using Sustainalytics.Entities.ESGRatings;
using Sustainalytics.ESGComputing.Service.Exceptions;
using Sustainalytics.ESGComputing.Service.Extensions;
using Sustainalytics.ESGComputing.Service.Infrastructure;
using Sustainalytics.ESGRatings.BusinessLogic.Computing;
using Sustainalytics.ESGRatings.DataContract;
using Sustainalytics.ESGRatings.DataContract.Mappers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;


namespace Sustainalytics.ESGComputing.Service.Controllers
{


    [RoutePrefix("api/v1/dataprovisioning/esgsets")]
    public class EsgDataContainerController : ApiController
    {
        private readonly ComputationEngine _engine;
        private readonly ESGSetLoader dataLoader;

        public EsgDataContainerController(ComputationEngine engine, ESGSetLoader dataLoader)
        {
            this.dataLoader = dataLoader;
            _engine = engine;
        }

        [Route]
        public HttpResponseMessage Delete(Guid setId)
        {
            _engine.DeleteSet(setId);
            return Request.CreateResponse(HttpStatusCode.OK);
        }

        [Route]
        public HttpResponseMessage Get(Guid? setId = null)
        {
            var data = _engine.ReadSets(setId, ComparativeGroupEnum.PeerGroup);

            return Request.CreateResponse(HttpStatusCode.OK, data.Select(x => new ESGDataContainerDTO { setId = x.Item1, isActive = x.Item2 }));
        }

        [Route]
        public HttpResponseMessage Post(ESGDataContainer data)
        {
            Guid id = LoadSetToEngine(data);

            return Request.CreateResponse(HttpStatusCode.Created, id);
        }

        [Route]
        public HttpResponseMessage Put([FromBody]ESGDataContainerDTO set)
        {
            var data = dataLoader.GetDataFromDatabase(set.setId == Guid.Empty ? (Guid?)null : set.setId).Result;
            data.IsActive = set.isActive;
            Guid id = LoadSetToEngine(data);

            return Request.CreateResponse(HttpStatusCode.Created, id);
        }

        [Route]
        public HttpResponseMessage Patch([FromBody]ESGDataContainerDTO data)
        {
            if (data == null)
            {
                return Request.CreateResponse(HttpStatusCode.BadRequest);
            }

            var set = _engine.ReadSets(data.setId, ComparativeGroupEnum.PeerGroup);
            if (set.Any(x => x.Item1 == data.setId))
            {
                _engine.SetActive(data.setId, data.isActive);
                return Request.CreateResponse(HttpStatusCode.Accepted);
            }
            return Request.CreateResponse(HttpStatusCode.BadRequest);
        }

        private Guid LoadSetToEngine(ESGDataContainer data)
        {
            ICollection<string> messages;
            if (data.Validate(out messages))
            {
                throw new InvalidInput(messages.Aggregate((i, j) => i + " " + j));
            }

            var id = _engine.AddESGSet(
                data.SetId,
                data.Companies.ToDomainModel().ToList(),
                data.IndicatorTemplates,
                data.CompaniesScores,
                data.Matrices,
                data.ReferenceUniverses,
                data.DefaultMatrixId,
                data.IsActive);
            return id;
        }
    }
}